home *** CD-ROM | disk | FTP | other *** search
- .TITLE HPWD
-
- ;++
- ; Hash Password
- ;
- ; Written by someone at DEC. Copied by Peter Kay for DIT CSIRO
- ;
- ;--
-
- .SBTTL DECLARATIONS
-
- ;
- ; Macros:
- ;
-
- .macro pushq Src
- movq Src,-(sp)
- .endm
-
- .macro popq Dst
- movq (sp)+,Dst
- .endm
-
- ;
- ; Equated symbols
- ;
-
- OUTDSC = 4 ; addr of encrypted output descriptor
- PWDDSC = OUTDSC + 4 ; addr of password descriptor
- ENCRYPT = PWDDSC + 4 ; Encryption algorithm index (byte)
- SALT = ENCRYPT + 4 ; random number (word)
- USRDSC = SALT + 4 ; addr of username descriptor
-
- ;
- ; Own Storage:
- ;
-
- .psect _LIB_CODE RD, NOWRT, PIC, SHR, BYTE, EXE
-
- ;
- ; Autodin-II polynomial table used by CRC algorithm
- ;
- AUTODIN:
- .LONG ^X00000000, ^X1DB71064, ^X386E2008, ^X26D930AC
- .LONG ^X76DC4190, ^X6B6B51F4, ^X4DB26158, ^X5005713C
- .LONG ^XEDB88320, ^XF00F9344, ^XD6D6A3E8, ^XCB61B38C
- .LONG ^X9B64C2B0, ^X86D3D2D4, ^XA00AE278, ^XBDBDF21C
-
- ; The following table of coefficients is used by the Purdy polynomial
- ; algorithm. They are prime, but the algorithm does not require this.
-
- C: .long -83, -1 ; C1
- .long -179, -1 ; C2
- .long -257, -1 ; C3
- .long -323, -1 ; C4
- .long -363, -1 ; C5
-
- .SBTTL Dispatch - select encryption algorithm
-
- ;++
- ;
- ; Functional Description:
- ;
- ; Smash up the password into a non-reversible number.
- ;
- ; Calling Sequence:
- ;
- ; CALLS/CALLG
- ;
- ; Formal Parameters:
- ;
- ; OUTDSC Descriptor of quadword descriptor to contain
- ; the results.
- ; PWDDSC Password descriptor
- ; ENCRYPT The encryption algorithm to be used
- ; SALT random number
- ; USRDSC Username descriptor
- ;--
-
- .entry LGI$HPWD,^M<R2, R3, R4, R5, R6> ; entry mask
-
- tstb ENCRYPT(ap) ; using CRC algorithm
- beql 20$ ; yes, no processing of usrdsc nesry
- subl2 #20, sp ; Get temp desc and buffer off stack
- movl sp, r6 ; put address in R6
- movq @USRDSC(ap), (r6) ; put current userdesc on stack
- cmpb #1, ENCRYPT(AP) ; which purdy algorithm
- bneq 10$
- movc5 (r6),@4(r6),#32,#12,8(r6) ; blank pad username
- movw #12,(r6) ; force length 12
- movab 8(r6),4(r6) ; desc on stack point to stack
- brb 20$ ; goto main line
-
- ; PURDY_V. remove padding in username
- 10$: movzwl (r6),r5 ; save length of username
- clrw (r6)
- movl 4(r6),r0 ; get address of username buffer
- 15$: cmpb (r0)+,#32 ; search until we find first blank
- beql 20$ ; found it
- incw (r6) ; increment until byte found
- cmpw #31,(r6) ; or 31 characters
- beql 20$ ; (31 is max username length)
- cmpw r5,(r6) ; or entire buffer has been parsed
- beql 20$
- brb 15$ ; loop
-
- 20$: movaq @PWDDSC(ap),r4 ; if password is zero length
- tstl (r4)
- bneq 25$ ; then return null password
- movaq @OUTDSC(ap),r4
- clrw (r4)
- movc5 #0,(r4),#0,#8,@4(r4) ; (quadword of zeros)
- brb 40$
-
- 25$: movaq @OUTDSC(ap),r4 ; get pointer to output buffer
- movaq @4(r4),r4 ;
- tstb ENCRYPT(ap) ; Use the CRC algorithm if the index
- bgtru 30$ ; is zero
- mnegl #1, r0 ; initial CRC
- movaq @PWDDSC(ap),r1 ; get descriptor address
- crc AUTODIN,r0,(r1),@4(r1) ; convert password to 32 bit number
- clrl r1 ; clear high order longword
- movq r0,(r4) ; copy results to output buffer
- brb 40$
-
- 30$: clrq (r4) ; initialize output buffer
- movaq @PWDDSC(ap),r3 ; Collapse password to quadword
- bsbb COLLAPSE_R2 ;
- addw2 SALT(ap),3(r4) ; add random salt into middle of quad
- movl r6,r3 ; Collapse username into the quadword
- bsbb COLLAPSE_R2 ;
- pushaq (r4) ; push pointer to U
- calls #1,Purdy ; Run U through poly mod P
-
- 40$: movl #1,r0
- ret
-
- COLLAPSE_R2:
- .enabl LSB
- ;++
- ; This routine takes a string of bytes (the descriptor for which is pointed
- ; to by r3) and collapses them into a quadword (pointed to by r4). It does
- ; this by cycling aroun the bytes of the output buffer adding in the bytes
- ; of the input string
- ;--
-
- movzwl (r3),r0 ; obtain the number of input bytes
- beqlu 20$
- moval @4(r3),r2 ; Obtain pointer to input string
- 10$: bicl3 #-8,r0,r1 ; Obtain cyclic index into output buf
- addb2 (r2)+,(r4)[r1]
- sobgtr r0,10$ ; Loop until input string is exhausted
- 20$: rsb
-
- .SBTTL Purdy - evaluate purdy polynomial
-
- a = 59 ; 2^64 - 59 is biggest quadword prime
-
- n0 = 1@24 - 3 ; These exponents are prime but this
- n1 = 1@24 - 63 ; not required by the algorithm
-
- .entry Purdy, ^M<r2,r3,r4,r5>
- ;
- ; This routine computes f(U) = p(U) mod P. Where P is a prime of the form
- ; P = 2^64 - a. The function P is the following polynomial:
- ; x^n0 + x^n1*C1 + x^3*C2 + x^2*C3 + x^2*C4 + C5
- ; The input U is an unsigned quadword
- ;
-
- pushq @4(ap) ; Push U
- bsbw PQMOD_R0 ; Ensure U less than P
- movaq (sp),r4 ; maintian a pointer to X
- movaq C,r5 ; Point to the table of coefficients
- pushq (r4)
- pushl #n1
- bsbb PQEXP_R3 ; X^n1
- pushq (r4)
- pushl #n0-n1
- bsbb PQEXP_R3 ;
- pushq (r5)+ ; C1
- bsbw PQADD_R0 ; x^(n0-n1) + C1
- bsbw PQMUL_R2 ; x^n0 + x^N1*C1
- pushq (r5)+ ; C2
- pushq (r4) ;
- bsbw PQMUL_R2 ; x*C2
- pushq (r5)+ ; C3
- bsbw PQADD_R0 ; x*C2 + C3
- pushq (r4) ;
- bsbb PQMUL_R2 ; x^2*C2 + x*C3
- pushq (r5)+ ; C4
- bsbw PQADD_R0 ; x^2*C2 + x*C3 + c4
- pushq (r4)
- bsbb PQMUL_R2 ; x^3*C3 + X^2*C3 + x*C4
- pushq (r5)+
- bsbw PQADD_R0 ; x^3*C3 + X^2*C3 + x*C4 + C5
- bsbw PQADD_R0 ; add in the high order terms
- popq @4(ap) ; replace U with F(x)
- movl #1,R0
- ret
-
- PQEXP_R3:
- .enabl LSB
- ; replace the inputs with U^n mod P where P is of the form P = 2^64 - a
- ; U is a quadword, n is an unsigned longword.
-
- popr #^M<r3> ; record return address
- pushq #1 ; initalize
- pushq 8+4(sp) ; copy U to top of stack for speed
- tstl 8+8(sp) ; only handle n gtr 0
- beqlu 30$
- 10$: blbc 8+8(sp),20$
- pushq (sp) ; Copy the current power of U
- pushq 8+8(sp) ; Multiply with current value
- bsbb PQMUL_R2 ;
- popq 8(sp) ; Replace current value
- cmpzv #1,#31,8+8(sp),#0 ;
- beqlu 30$
- 20$: pushq (sp) ; Proceed to next power of U
- bsbb PQMUL_R2 ;
- extzv #1,#31,8+8(sp),8+8(sp) ;
- brb 10$
- 30$: movq 8(sp),8+8+4(sp) ; copy the return value
- movaq 8+8+4(sp),sp ; discard exponent
- jmp (r3) ; return
- .dsabl LSB
-
- u=0 ; low longword of U
- v=u+4 ; High longword of U
- y=u+8 ; low longword of Y
- z=y+4 ; High longword of Y
-
- PQMOD_R0:
- .enabl LSB
- ; Replaces the quadword U on the stack with U mod P where P is of the
- ; form 2^64 - a.
-
- popr #^M<r0>
- cmpl v(sp),#-1
- blssu 10$
- cmpl u(sp),#-a
- blssu 10$
- addl2 #a,u(sp)
- adwc #0,v(sp)
- 10$: jmp (r0)
- .dsabl LSB
-
- PQMUL_R2:
- ; computes the product U*Y mod P where P is of the form 2^64 - a.
- ; U, Y are quadwords less than P. The product replaces U and Y on the stack.
-
- ; The product may be formed as the sum of four longword multiplications
- ; which are scaled by powers of 2^32 by evaluating
- ; 2^64*v*z + 2^32*(v*y+u*z) + u*y
- ; The result is computed such that division by the modulus P is avoided
-
- popr #^M<r1> ; Record return address
- movl sp,r2
- pushl z(r2)
- pushl v(r2)
- bsbb EMULQ
- bsbb PQMOD_R0
- bsb PQLSH_R0
- pushl y(r2)
- pushl v(r2)
- bsbb EMULQ
- bsbb PQMOD_R0
- pushl z(r2)
- pushl u(r2)
- bsbb EMULQ
- bsbb PQMOD_R0
- bsbb PQADD_R0
- bsbb PQADD_R0
- bsbb PQLSH_R0
- pushl y(r2)
- pushl u(r2)
- bsbb EMULQ
- bsbb PQMOD_R0
- bsbb PQADD_R0
- popq y(r2)
- movaq y(r2),sp
- jmp (r1)
-
- EMULQ:
- .enable LSB
- ; This routine knows how to multiply to unsigned longwords, replacing them
- ; with the unsigned quadword product on the stack.
-
- emul 4(sp),8(sp),#0,-(sp)
- clrl -(sp)
- tstl 4+8+4(sp) ; check both longwords to see if must
- bgeq 10$ ; unsigned bias
- addl 4+8+8(sp), (sp)
- 10$: tstl 4+8+8(sp)
- bgeq 20$
- addl 4+8+4(sp),(sp)
- 20$: addl (sp)+,4(sp)
- popq 4(sp)
- rsb
- .dsabl LSB
-
- PQLSH_R0:
- .enabl LSB
- ; Computes the product 2^32*U mod P where P is of the form P = 2^64 - a.
- ; U is a quadword less than P. the product replaces U on the stack.
-
- ; This routine is used by PQMUL in the formation of quadword products in
- ; such a way as to avoid division by by the modulus P.
- ; The product 2^64*v + 2^32*u is congruent a*v + 2^32*u mod P (where u, v
- ; are longwords).
-
- popr #^M<R0> ; record return in r0
- pushl v(sp)
- pushl #a
- bsbb EMULQ ; push a*v
- ashq #32,Y(sp),y(sp) ; form y = 2^32*u
- brb 10$
-
- PQADD_R0:
- ; Computes the sum U + Y mod P where P is of the form P = 2^64 - a;
- ; U, Y are quadword less than P. The sum replaces U and Y on the stack.
- popr #^M<r0> ; Record return address
- 10$: addl u(sp),y(sp) ; add the low longwords
- adwc v(sp),z(sp) ; add the high longwords with carry
- bcs 20$
- cmpl z(sp),#-1
- blssu 30$
- cmpl y(sp),#-a
- blssu 30$
- 20$: addl2 #a,y(sp)
- adwc #0,z(sp)
- 30$: movaq y(sp),sp
- jmp (r0)
- .dsabl LSB
-
- .END
-